package com.ruoyi.core.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.entity.CoreEntity.Members;
import com.ruoyi.common.entity.CoreEntity.PointRecords;
import com.ruoyi.common.entity.CoreEntity.SignIns;
import com.ruoyi.core.service.IMembersService;
import com.ruoyi.core.service.IPointRecordsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.core.mapper.SignInsMapper;

import com.ruoyi.core.service.ISignInsService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户签到记录Service业务层处理
 * 
 * @author 亢哲
 * @date 2025-08-07
 */
@Service
public class SignInsServiceImpl implements ISignInsService 
{
    @Autowired
    private SignInsMapper signInsMapper;
    @Autowired
    private IPointRecordsService pointRecordsService;
    // 添加依赖注入
    @Autowired
    private IMembersService membersService;

    @Override
    @Transactional
    public Map<String, Object> userSignIn(Long userId) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 检查今天是否已签到
            Date today = new Date();
            SignIns todaySignIn = signInsMapper.checkTodaySignIn(userId, today);
            if (todaySignIn != null) {
                result.put("success", false);
                result.put("message", "今天已经签到过了");
                return result;
            }

            // 2. 计算连续签到天数和积分
            SignInResult signInResult = calculateSignInPoints(userId);

            // 3. 获取用户当前积分余额（从members表）
            Members member = membersService.selectMembersById(userId);
            if (member == null) {
                throw new RuntimeException("用户不存在");
            }

            Long currentPoints = member.getPointsTotal();
            if (currentPoints == null) {
                currentPoints = 0L; // 新用户，积分为0
            }

            // 4. 计算签到后的积分余额
            Long newPointsBalance = currentPoints + signInResult.getPointsEarned();

            // 5. 更新用户总积分（在members表中）
            member.setPointsTotal(newPointsBalance);
            membersService.updateMembers(member);

            // 6. 创建签到记录
            SignIns newSignIn = new SignIns();
            newSignIn.setUserId(userId);
            newSignIn.setSignDate(today);
            newSignIn.setContinuousDays(signInResult.getContinuousDays());
            newSignIn.setPointsEarned(signInResult.getPointsEarned());
            newSignIn.setPointsAfterSign(newPointsBalance); // 记录签到后的积分余额
            newSignIn.setSignType(signInResult.getSignType());

            // 7. 插入签到记录
            int signInInsertResult = signInsMapper.insertSignIns(newSignIn);
            if (signInInsertResult <= 0) {
                throw new RuntimeException("签到记录插入失败");
            }

            // 8. 记录积分明细
            PointRecords pointRecord = new PointRecords();
            pointRecord.setUserId(userId);
            pointRecord.setType(1L); // 1-签到
            pointRecord.setPoints(signInResult.getPointsEarned()); // 正数，表示增加积分
            pointRecord.setRelatedId(newSignIn.getId());
            pointRecord.setDescription(signInResult.getDescription());
            pointRecord.setPointsBalance(newPointsBalance); // 记录变动后的积分余额
            pointRecord.setCreatedAt(today);
            pointRecordsService.insertPointRecords(pointRecord);

            result.put("success", true);
            result.put("message", "签到成功");
            result.put("pointsEarned", signInResult.getPointsEarned());
            result.put("continuousDays", signInResult.getContinuousDays());
            result.put("totalPoints", newPointsBalance);

        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "签到失败：" + e.getMessage());
            throw new RuntimeException("签到失败", e);
        }

        return result;
    }

    /**
     * 计算签到积分和连续天数
     */
    private SignInResult calculateSignInPoints(Long userId) {
        SignInResult result = new SignInResult();

        // 获取最后一次签到记录
        SignIns lastSignIn = signInsMapper.selectLastSignIn(userId);

        if (lastSignIn == null) {
            // 第一次签到
            result.setContinuousDays(1L);
            result.setPointsEarned(5L);
            result.setSignType(1L); // 普通签到
            result.setDescription("每日签到");
            return result;
        }

        // 计算距离上次签到的天数
        long daysBetween = calculateDaysBetween(lastSignIn.getSignDate(), new Date());

        if (daysBetween == 1) {
            // 连续签到
            Long newContinuousDays = lastSignIn.getContinuousDays() + 1;
            result.setContinuousDays(newContinuousDays);

            // 计算积分：基础5分 + (连续天数-1) * 2分，最大到第7天
            if (newContinuousDays <= 7) {
                result.setPointsEarned(5L + (newContinuousDays - 1) * 2);
            } else {
                result.setPointsEarned(5L + (7 - 1) * 2); // 第7天及以后的积分
            }

            result.setSignType(2L); // 连续签到
            result.setDescription("连续签到第" + newContinuousDays + "天");
        } else {
            // 中断签到，重新开始
            result.setContinuousDays(1L);
            result.setPointsEarned(5L);
            result.setSignType(1L); // 普通签到
            result.setDescription("签到中断，重新开始");
        }

        return result;
    }

    /**
     * 计算两个日期之间的天数差
     */
    private long calculateDaysBetween(Date date1, Date date2) {
        long diffInMillies = Math.abs(date2.getTime() - date1.getTime());
        return diffInMillies / (24 * 60 * 60 * 1000);
    }

    /**
     * 签到结果内部类
     */
    private static class SignInResult {
        private Long continuousDays;
        private Long pointsEarned;
        private Long signType;
        private String description;

        // getters and setters
        public Long getContinuousDays() { return continuousDays; }
        public void setContinuousDays(Long continuousDays) { this.continuousDays = continuousDays; }

        public Long getPointsEarned() { return pointsEarned; }
        public void setPointsEarned(Long pointsEarned) { this.pointsEarned = pointsEarned; }

        public Long getSignType() { return signType; }
        public void setSignType(Long signType) { this.signType = signType; }

        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
    }

    /**
     * 查询用户签到记录
     * 
     * @param id 用户签到记录主键
     * @return 用户签到记录
     */
    @Override
    public SignIns selectSignInsById(Long id)
    {
        return signInsMapper.selectSignInsById(id);
    }

    /**
     * 查询用户签到记录列表
     * 
     * @param signIns 用户签到记录
     * @return 用户签到记录
     */
    @Override
    public List<SignIns> selectSignInsList(SignIns signIns)
    {
        return signInsMapper.selectSignInsList(signIns);
    }

    /**
     * 新增用户签到记录
     * 
     * @param signIns 用户签到记录
     * @return 结果
     */
    @Override
    public int insertSignIns(SignIns signIns)
    {
        return signInsMapper.insertSignIns(signIns);
    }

    /**
     * 修改用户签到记录
     * 
     * @param signIns 用户签到记录
     * @return 结果
     */
    @Override
    public int updateSignIns(SignIns signIns)
    {
        return signInsMapper.updateSignIns(signIns);
    }

    /**
     * 批量删除用户签到记录
     * 
     * @param ids 需要删除的用户签到记录主键
     * @return 结果
     */
    @Override
    public int deleteSignInsByIds(Long[] ids)
    {
        return signInsMapper.deleteSignInsByIds(ids);
    }

    /**
     * 删除用户签到记录信息
     * 
     * @param id 用户签到记录主键
     * @return 结果
     */
    @Override
    public int deleteSignInsById(Long id)
    {
        return signInsMapper.deleteSignInsById(id);
    }
}
